from django.contrib.auth import login, logout, authenticate
from django.middleware import http
import json
import re
from django.shortcuts import render
from django.http import JsonResponse
from django.utils import timezone
from django import http
from django.views import View
from django_redis import get_redis_connection
from fdfs_client.client import Fdfs_client

from apps.users.models import User
from django.conf import settings
from apps.house.models import House
from aijia_house.utils.views import LoginRequiredJSONMixin


class RegisterView(View):
    def post(self, request):
        '''接收参数, 保存到数据库'''
        # 1.接收参数：请求体中的JSON数据 request.body
        json_dict = json.loads(request.body.decode())
        # 提取参数
        password = json_dict.get('password')
        password2 = json_dict.get('password2')
        mobile = json_dict.get('mobile')
        # allow = json_dict.get('allow')
        phonecode = json_dict.get('phonecode')

        # 2.校验(整体参数是否为空)
        if not all([password, password2, mobile, phonecode]):
            return http.JsonResponse({"errno": 4004, 'errmsg': '缺少必传参数!'})
        # 4.password检验
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return http.JsonResponse({"errno": 4004, 'errmsg': 'password格式有误!'})

        # 5.password2 和 password
        if password != password2:
            return http.JsonResponse({"errno": 4004, 'errmsg': '两次输入不对!'})
        # 6.mobile检验
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.JsonResponse({"errno": 4004, 'errmsg': 'mobile格式有误!'})
        # 判断短信验证码是否正确：跟图形验证码的验证一样的逻辑
        # 提取服务端存储的短信验证码：以前怎么存储，现在就怎么提取
        redis_conn = get_redis_connection('verify_code')
        phonecode_server = redis_conn.get("sms_%s" % mobile)  # phonecode_server是bytes
        # 判断短信验证码是否过期
        if not phonecode_server:
            return http.JsonResponse({"errno": 4004, 'errmsg': '短信验证码失效'})
        # 对比用户输入的和服务端存储的短信验证码是否一致
        if phonecode != phonecode_server.decode():
            return http.JsonResponse({"errno": 4004, 'errmsg': '短信验证码有误'})

        # 8.注册的核心逻辑-保存到数据库 (mobile password mobile)
        try:
            user = User.objects.create_user(username=mobile, password=password, mobile=mobile)
        except Exception as e:
            return http.JsonResponse({"errno": 4004, 'errmsg': '注册失败!'})

        # 状态保持
        login(request, user)
        return http.JsonResponse({"errno": 0, "errmsg": "OK"})


# 1.判断手机号是否重复注册
class MobileCountView(View):

    def get(self, request, mobile):
        '''判断手机号是否重复注册'''
        # 1.查询mobile在mysql中的个数
        try:
            count = User.objects.filter(mobile=mobile).count()
        except Exception as e:
            return http.JsonResponse({"errno": "0", "errmsg": "ok"})

        # 2.返回结果(json)
        return http.JsonResponse({"errno": "0", "errmsg": "ok"})


# 3.用户登录
class LoginView(View):
    def post(self, request):
        # 1.接收参数,提取参数
        json_dict = json.loads(request.body.decode())
        mobile = json_dict.get('mobile')
        password = json_dict.get('password')
        # 2.校验参数--判空,和正则
        if not all([mobile, password]):
            return http.JsonResponse({"errno": 400, 'errmsg': '缺少必传参数'})

        # 3.数据库进行判断,看用户名和密码是否一致
        # authenticate判断登录 密码加密对比

        user = authenticate(request, username=mobile, password=password)
        if user is None:
            return JsonResponse({"errno": 4004, 'errmsg': '用户名或者密码错误'})
        # 保持登录状态
        login(request, user)
        # 2. 从数据库查询出指定的用户

        # 返回响应结果

        # 在响应对象中设置用户名信息.
        # 将用户名写入到 cookie，有效期 14 天
        # response.set_cookie('mobile', user.mobile, max_age=3600 * 24 * 14)

        # 返回响应结果
        return JsonResponse({"errno": 0, 'errmsg': 'ok'})


# 用户退出登录
#     退出登录
class LogoutView(View):
    def delete(self, request):
        # 删除session
        logout(request)
        # 创建 response 对象.
        response = JsonResponse({"errno": "0", "errmsg": "ok"})

        # 调用对象的 delete_cookie 方法, 清除cookie
        # 删除cookie的用户名
        response.delete_cookie('mobile')
        return response


class Session(View):
    '''用户状态查询'''

    def get(self, request):
        """
        检测用户是否登录，如果登录，则返回用户的名和用户id
        """
        user = request.user
        if user.is_authenticated:
            data = {'user_id': user.id, 'name': user.username}
            return http.JsonResponse({'errno': 0, 'errmsg': "OK", 'data': data})
        else:
            return http.JsonResponse({'errno': 4004, 'errmsg': '用户未登录'})


# Create your views here.


"""
    接口文档:
        1.接口：获取/修改用户真实姓名
        2.请求方式:get/post
        3.参数：real_name，id_card
        4.响应：json
"""


class UserRealInfoView(View):
    '''认证实名信息'''

    def get(self, request):
        data = {
            'real_name': request.user.real_name,
            'id_card': request.user.id_card
        }
        return JsonResponse({"errno": 0, 'errmsg': 'OK', 'data': data})

    def post(self, request):
        user = request.user
        json_dict = json.loads(request.body.decode())
        real_name = json_dict.get('real_name')
        id_card = json_dict.get('id_card')

        user.real_name = real_name
        user.id_card = id_card
        try:
            user.save()
        except Exception as e:
            return JsonResponse({"erron": 4001, 'errmsg': '保存数据失败'})
        return JsonResponse({"erron": 0, 'errmsg': '保存成功'})


"""
    接口文档:
            1.接口：上传图片
            2.请求方式:post
            3.参数：
            4.响应：json
"""


class UserImageView(LoginRequiredJSONMixin, View):
    def post(self, request):
        # 获取文件
        image = request.FILES.get('avatar')
        # 判空
        if image is None:
            return JsonResponse({"erron": 4103, 'errmsg': '图片参数错误'})
        # 将文件上传至FDFS
        try:
            client = Fdfs_client(settings.FDFS_CLIENT_CONF)
            result = client.upload_by_buffer(image.read())
        except Exception as e:
            return JsonResponse({"erron": 4001, 'errmsg': '图片上传失败'})

        # 上传成功：返回file_id,拼接图片访问URL
        file_id = result.get('Remote file_id')
        url = settings.FDFS_BASE_URL + file_id

        # 将头像信息保存到用户模型
        user = request.user
        user.avatar_url = url
        user.save()

        # 4. 返回上传的结果<avatar_url>
        return http.JsonResponse({'errno': 0, 'errmsg': "OK", 'data': {"avatar_url": url}})


"""
    接口文档:
        1.接口：获取/修改用户信息
        2.请求方式:get/post
        3.参数：name，avatar_url，mobile
        4.响应：json
"""


class UserInfoView(View):

    def get(self, request):

        data = {
            "name": request.user.username,
            "avatar_url": request.user.avatar_url,
            "mobile": request.user.mobile,
        }
        return JsonResponse({'errno': 0, 'errmsg': "OK", 'data': data})

    def post(self, request):
        data_dict = json.loads(request.body.decode())
        name = data_dict.get('name')
        if name is None:
            return JsonResponse({'errno': 4103, 'errmsg': '参数错误'})
        user = request.user
        try:

            user.username = name
            user.save()
        except Exception as e:
            return JsonResponse({'errno': 4001, 'errmsg': "保存数据失败"})

        return JsonResponse({'errno': 0, 'errmsg': "OK"})


from django.shortcuts import render
from django.utils import timezone
from django.views import View
from django import http


class HouseResourcesView(View):

    def get(self, request):

        # 获取所有房源
        try:
            houses = House.objects.filter(user=request.user)
            print(houses)
        except Exception as e:
            return http.JsonResponse({'errno': 4001, 'errmsg': '数据库查询错误'})
        # 创建键空列表
        house_dict_list = []
        for house in houses:
            house_dict = {

                'area_name': house.area.name,
                'ctime': timezone.localtime().strftime('%Y-%m-%d'),
                'house_id': house.id,
                'img_url': house.index_image_url,
                'order_count': house.order_count,
                'price': house.price,
                'room_count': house.room_count,
                'title': house.title,
                'user_avatar': house.user.avatar_url
            }
            house_dict_list.append(house_dict)

        return http.JsonResponse({'errno': 0, 'errmsg': 'ok', 'data': house_dict_list})
